<?php


namespace UU\Suite\DingTalk;


use App\Service\CorpComponentService;
use GuzzleHttp\Client;
use Hyperf\Contract\ConfigInterface;
use Hyperf\Guzzle\HandlerStackFactory;
use Psr\SimpleCache\CacheInterface;

class DingLogin
{
    /**
     * @var Client
     */
    protected $httpClient;
    /**
     * @var CacheInterface|null
     */
    protected $cache;


    protected string $appId;
    protected string $secret;
    protected ?string $key = null;

    public function __construct(
        ConfigInterface $config,
        CacheInterface $cache
    )
    {
        $this->appId = $config->get('ding.appId', '');
        $this->secret = $config->get('ding.secret', '');
        $this->cache = $cache;
        $this->httpClient = new Client(
            ['base_uri' => 'https://oapi.dingtalk.com', 'handler' => di(HandlerStackFactory::class)->create()]
        );
    }

    public function getKey(): string
    {
        return $this->key ?? $this->key = \sprintf('login_accou1nt_token.access_token.%s', $this->appId);
    }

    public function setKey(string $key): self
    {
        $this->key = $key;
        return $this;
    }

    /**
     */
    public function getToken(): string
    {
        $key = $this->getKey();

        if ($token = $this->cache->get($key)) {
            return $token;
        }
        $response = json_decode($this->httpClient->get(
            '/sns/gettoken',
            [
                'query' => [
                    'appid' => $this->appId,
                    'appsecret' => $this->secret,
                ],
            ]
        )->getBody()->getContents(), true);

        p($response);

        if (empty($response['access_token'])) {
            throw new \Exception('Failed to get access_token.');
        }
        $this->cache->set($key, $response['access_token'], \intval($response['expires_in'] ?? 7200) - 100);
        return $response['access_token'];
    }


    public function code2userinfo($appid,$code): array
    {
//        $query = $this->getCheckParams($this->appId, $this->secret);
        $response = json_decode($this->httpClient->post(
            '/sns/get_persistent_code',
            [
                'query' => [
                    'access_token' => $this->getToken(),
                ],
                'json' => [
                    'tmp_auth_code' => $code
                ]
            ]
        )->getBody()->getContents(), true);
        /** @var Application $app */
        $app = make(CorpComponentService::class)->getApp($appid);
        $res = $app->getClient()->get(
            '/user/getUseridByUnionid',
            [
                'query' => [
                    'access_token' => $app->getAccessToken()->getToken(),
                    'unionid' => $response['unionid'] ?? '',

                ]
            ]
        );
        $response['userid'] = $res['userid'] ?? 0;
        return $response;
    }

//    /**
//     * Description: 个人免登场景的签名计算方法
//     * Author: WangSx
//     * DateTime: 2019-11-04 19:11.
//     * @return array
//     * @throws \Exception
//     */
//    protected function getCheckParams($accessKey,$appSecret)
//    {
//        // 根据timestamp, appSecret计算签名值
//        $timestamp = (string)(time() * 1000);
//        $s = hash_hmac('sha256', $timestamp, $appSecret, true);
//        $signature = urlencode(base64_encode($s));
//        return compact('signature', 'timestamp', 'accessKey');
//
//    }
}